﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace HomeService.Models
{
    public class ValidationException : Exception
    {
        public readonly IList<ValidationError> Errors = new List<ValidationError>();
        private static readonly Expression<Func<object, object>> ThisObject = x => x;

        public void AddErrorForModel(string message)
        {
            Errors.Add(new ValidationError { Property = ThisObject, Message = message });
        }

        public void ThrowIfErrors()
        {
            if (Errors.Any())
                throw this;
        }

        public class ValidationError
        {
            public LambdaExpression Property { get; set; }
            public string Message { get; set; }
        }
    }

    public class ValidationException<TModel> : ValidationException
    {
        public void AddErrorFor<TProperty>(Expression<Func<TModel, TProperty>> property, string message)
        {
            Errors.Add(new ValidationError { Property = property, Message = message });
        }
    }

    internal static class RulesViolationExceptionExtensions
    {
        public static void CopyTo(this ValidationException ex, ModelStateDictionary modelState)
        {
            CopyTo(ex, modelState, null);
        }

        public static void CopyTo(this ValidationException ex, ModelStateDictionary modelState, string prefix)
        {
            prefix = string.IsNullOrEmpty(prefix) ? "" : prefix + ".";
            foreach (var propertyError in ex.Errors) {
                var key = ExpressionHelper.GetExpressionText(propertyError.Property);
                modelState.AddModelError(prefix + key, propertyError.Message);
            }
        }
    }
}